﻿using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZX.EHR.Library;
using ZX.BLL.Extend;
using ZX.DBModule;
using System.Reflection;
using System.CodeDom.Compiler;
using System;
using Microsoft.CSharp;
using ZX.DAL.DBExtend;

namespace ZX.BLL
{
    /// <summary>
    /// 薪资表达式解析类
    /// </summary>
    public class SalaryFormulaResolveTemp
    {
        #region 计算工资SQL方式
        /// <summary>
        /// 计算所有员工薪资
        /// </summary>
        public static void CalEmployeeSalarySQL()
        {
            DateTime dt = DateTime.Now.AddMonths(-1);//上一个月
            string yearMonth = dt.ToString("yyyy-MM");
            CalClientEmployeeSalarySQL(yearMonth);
        }

        /// <summary>
        /// 供客户端调用,计算工资
        /// </summary>
        /// <param name="yearMonth"></param>
        public static void CalClientEmployeeSalarySQL(string yearMonth)
        {
            try
            {
                //变量定义
                DbSql dbsql = new DbSql();
                //计算所有员工薪资
                int count = dbsql.GetRowCount("hrEmployee", "EmployeeStatus=1");
                int PageIndex = 1;
                int PageSize = 20;
                int currentCount = 0;
                int currentPageSize = PageSize;
                string sql = string.Empty;
                while (currentCount < count)
                {
                    if ((count - (PageIndex - 1) * PageSize) < PageSize)
                    {
                        currentPageSize = count - PageIndex * PageSize > 0 ? count - PageIndex * PageSize : count;
                    }
                    sql = "select a.ID from (select top " + currentPageSize + " * from hrEmployee where EmployeeStatus=1 and ID not in(select top " + (PageIndex - 1) * PageSize + " ID from hrEmployee order by ID) order by ID) a";
                    System.Data.DataTable empDt = dbsql.ExecuteQuery(sql);
                    if (empDt != null && empDt.Rows.Count > 0)
                    {
                        for (int i = 0; i < empDt.Rows.Count; i++)
                        {
                            string empId = empDt.Rows[i][0].ToString();
                            if (empId == null || empId == string.Empty) continue;
                            SalaryFormulaResolveTemp.CalcEmployeeSalarySQL(empId, yearMonth);
                        }
                    }
                    currentCount += PageSize;
                    PageIndex++;
                }
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
            }
        }

        /// <summary>
        /// 单独计算某个人的薪资
        /// </summary>
        /// <param name="emp"></param>
        /// <param name="yearMonth"></param>
        public static void CalSingleEmployeeSalarySQL(string empId, string yearMonth)
        {
            SalaryFormulaResolveTemp.CalcEmployeeSalarySQL(empId, yearMonth);
        }

        /// <summary>
        /// 计算某部门员工薪资
        /// </summary>
        /// <param name="deptId"></param>
        /// <param name="yearMonth"></param>
        public static void CalDeptEmployeeSalarySQL(string deptId, string yearMonth)
        {
            try
            {
                //变量定义
                DbSql dbsql = new DbSql();
                string sql = "select ID from hrEmployee where DepartmentID='" + deptId + "' and EmployeeStatus=1";
                System.Data.DataTable empDt = dbsql.ExecuteQuery(sql);
                if (empDt == null || empDt.Rows.Count == 0) return;
                for (int i = 0; i < empDt.Rows.Count; i++)
                {
                    string empId = empDt.Rows[i][0].ToString();
                    if (empId != null && empId != string.Empty)
                    {
                        CalSingleEmployeeSalarySQL(empId, yearMonth);//计算员工薪资
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
            }
        }
        #endregion

        #region 计算工资业务类实现
        /// <summary>
        /// 计算所有员工薪资
        /// </summary>
        public static void CalEmployeeSalary()
        {
            DateTime dt = DateTime.Now.AddMonths(-1);//上一个月
            string yearMonth = dt.ToString("yyyy-MM");
            CalClientEmployeeSalary(yearMonth);
        }

        /// <summary>
        /// 供客户端调用,计算工资
        /// </summary>
        /// <param name="yearMonth"></param>
        public static void CalClientEmployeeSalary(string yearMonth)
        {
            //变量定义
            BaseBussnies<hrEmployee> empbll = new BaseBussnies<hrEmployee>(new hrEmployee());
            //计算所有员工薪资
            int count = empbll.GetRowCount("EmployeeStatus=1");
            empbll.PageIndex = 1;
            empbll.PageSize = 20;
            empbll.Order = "ID";
            empbll.Desc = "Yes";
            int currentCount = 0;
            while (currentCount < count)
            {
                IList<BaseEntity> empLists = empbll.GetEntitysSplitPage("EmployeeStatus=1");
                foreach (BaseEntity entityEmp in empLists)
                {
                    hrEmployee emp = entityEmp as hrEmployee;
                    SalaryFormulaResolveTemp.CalcEmployeeSalary(emp, yearMonth);
                }
                currentCount += empbll.PageSize;
                empbll.PageIndex++;
            }
        }

        /// <summary>
        /// 单独计算某个人的薪资
        /// </summary>
        /// <param name="emp"></param>
        /// <param name="yearMonth"></param>
        public static void CalSingleEmployeeSalary(hrEmployee emp, string yearMonth)
        {
            SalaryFormulaResolveTemp.CalcEmployeeSalary(emp, yearMonth);
        }

        /// <summary>
        /// 计算某部门员工薪资
        /// </summary>
        /// <param name="deptId"></param>
        /// <param name="yearMonth"></param>
        public static void CalDeptEmployeeSalary(string deptId, string yearMonth)
        {
            hrEmployee employee = new hrEmployee();
            BaseBussnies empbll = new BaseBussnies(employee);
            //获取该部门下所有人员
            IList<BaseEntity> lists = empbll.GetEntitysByCondition("DepartmentID='" + deptId + "' and EmployeeStatus=1");
            foreach (BaseEntity entity in lists)
            {
                employee = entity as hrEmployee;
                CalSingleEmployeeSalary(employee, yearMonth);//计算该员工薪资
            }
        }
        #endregion

        #region 采用SQL语句来解析
        /// <summary>
        /// 计算员工某个月份的工资
        /// </summary>
        /// <param name="empId">员工ID</param>
        /// <param name="yearMonth">年月</param>
        static void CalcEmployeeSalarySQL(string empId, string yearMonth)
        {
            try
            {
                DbSql dbsql = new DbSql();
                //根据员工ID获取薪资方案,计算其薪资
                //先判断是不否有个人薪资方案
                string sql = "select SolutionID from salDeptSolution where DeptID='" + empId + "' and Flag=2";
                object deptSolution = dbsql.GetSingle(sql);
                if (deptSolution == null)//没有个人对应的薪资方案
                {
                    //查找相应的岗位薪资方案
                    //获取岗位
                    sql = "select PostID,DepartmentID from hrEmployee where ID='" + empId + "'";
                    System.Data.DataTable dt = dbsql.ExecuteQuery(sql);
                    if (dt == null || dt.Rows.Count > 0)
                    {
                        string postId = dt.Rows[0][0].ToString();
                        if (postId != string.Empty)
                        {
                            sql = "select SolutionID from salDeptSolution where DeptID='" + postId + "' and Flag=1";
                            deptSolution = dbsql.GetSingle(sql);
                        }
                        if (deptSolution == null)//没有岗位对应的薪资方案
                        {
                            string deptId = dt.Rows[0][1].ToString();
                            sql = "select SolutionID from salDeptSolution where DeptID='" + deptId + "' and Flag=0";
                            deptSolution = dbsql.GetSingle(sql);
                        }
                    }
                }
                if (deptSolution == null) return;
                //获取薪资方案所有薪资项
                sql = "select Formula,ItemName from salSalaryItem where SalarySolutionID='" + deptSolution.ToString() + "'";
                System.Data.DataTable salaryItems = dbsql.ExecuteQuery(sql);
                //计算各薪资项的值
                //先删除该员工该年月薪资数据
                dbsql.RunSqlCommand("delete from salEmployeeSalaryResult where EmployeeID='" + empId + "' and YearMonth='" + yearMonth + "'");
                //查找UserId
                sql = "select UserID from DatUser where EmpID='" + empId + "'";
                object user = dbsql.GetSingle(sql);
                string userId = string.Empty;
                if (user != null) userId = user.ToString();
                //构建薪资插入或更新SQL语句
                string rsSql = "insert into salEmployeeSalaryResult(ID,SalarySultionID,EmployeeID,YearMonth,BeginDate,EndDate,CalDate,AddUser";
                List<double> resultLists = new List<double>();
                if (salaryItems == null || salaryItems.Rows.Count == 0) return;
                for (int i = 0; i < salaryItems.Rows.Count; i++)
                {
                    string itemFormula = salaryItems.Rows[i][0].ToString();
                    string itemName = salaryItems.Rows[i][1].ToString();
                    double rs = GetInitialFormulaDataValueSQL(itemFormula, empId, yearMonth, deptSolution.ToString());//计算结果
                    rsSql += "," + itemName;
                    resultLists.Add(rs);//保存到结果列表中
                }
                DateTime date = DateTime.Parse(yearMonth);
                string startDate = date.ToString("yyyy-MM-dd");
                date = date.AddMonths(1);
                date = date.AddDays(-1);
                string endDate = date.ToString("yyyy-MM-dd");
                rsSql += ") values(newid(),'" + deptSolution.ToString() + "','" + empId + "','" + yearMonth + "','" + startDate + "','" + endDate + "','" + DateTime.Now.ToString("yyyy-MM-dd") + "','" + userId + "'";
                foreach (double d in resultLists)
                {
                    rsSql += "," + d;
                }
                rsSql += ")";
                //将数据插入结果表
                dbsql.RunSqlCommand(rsSql);
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
            }
        }

        /// <summary>
        /// 将蒋项表达式转换成原始表达式
        /// </summary>
        /// <param name="formula"></param>
        /// <param name="salarySolutionId"></param>
        /// <returns></returns>
        static string GetInitialExpressionSQL(string formula, string salarySolutionId)
        {
            try
            {
                string rsstr = formula;
                string sql = string.Empty;
                DbSql dbsql = new DbSql();
                //替换函数为表达式
                while (rsstr.Contains("<"))
                {
                    //先找出<函数>
                    int startIndex = rsstr.IndexOf("<");
                    int endIndex = rsstr.IndexOf(">");
                    //函数名
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    string funName = replacedStr.Substring(1, replacedStr.Length - 2);
                    //获取函数表达式
                    sql = "select ID,rsReturn from salSalaryFunction where Name='" + funName + "'";
                    System.Data.DataTable funDt = dbsql.ExecuteQuery(sql);
                    string returnStr = "0";
                    if (funDt != null && funDt.Rows.Count > 0) //薪资函数存在,不存在该函数则为0
                    {
                        string funId = funDt.Rows[0][0].ToString();
                        //函数返回表达式
                        returnStr = funDt.Rows[0][1].ToString();
                        //函数有返回值表明该函数是表达式函数,否则在GetInitialFormulaDataValue获取其值
                        if (returnStr.Trim() != string.Empty)
                        {
                            //把函数中的参数替换为值
                            while (returnStr.Contains("<"))
                            {
                                //先找出<参数>
                                int index1 = returnStr.IndexOf("<");
                                int index2 = returnStr.IndexOf(">");
                                string replacedParamStr = returnStr.Substring(index1, index2 - index1 + 1);
                                //参数名
                                string paramName = replacedParamStr.Substring(1, replacedParamStr.Length - 2);
                                //获取参数值
                                sql = "select DataValue from salSalaryFunctionParameter where Parameter='" + paramName + "' and SalaryFunctionID='" + funId + "'";
                                object salaryParam = dbsql.ExecuteQuery(sql);
                                returnStr = returnStr.Replace(replacedParamStr, salaryParam.ToString());
                            }
                            rsstr = rsstr.Replace(replacedStr, "(" + returnStr + ")");
                        }
                        else //表明该函数为后台反射调用执行的函数
                        {
                            //这类函数用@函数名#标示
                            rsstr = rsstr.Replace(replacedStr, "@" + funName + "#");
                        }
                        //递归替换表达式
                        rsstr = GetInitialExpressionSQL(rsstr, salarySolutionId);
                    }
                }
                //替换薪资项为表达式
                while (rsstr.Contains("{"))
                {
                    //先找出{薪资项}
                    int startIndex = rsstr.IndexOf("{");
                    int endIndex = rsstr.IndexOf("}");
                    //要替换的
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    //薪资项目说明
                    string salaryItemNote = replacedStr.Substring(1, replacedStr.Length - 2);
                    //获取薪资项表达式
                    sql = "select DataSource from salSalaryItem where ItemNotes='" + salaryItemNote + "' and SalarySolutionID='" + salarySolutionId + "'";
                    object salaryItemDataSource = dbsql.GetSingle(sql);
                    if (salaryItemDataSource == null) //该薪资方案中不存在该薪资项
                    {
                        rsstr = rsstr.Replace(replacedStr, "0");
                    }
                    else
                    {
                        rsstr = rsstr.Replace(replacedStr, "(" + salaryItemDataSource + ")");
                    }
                    //递归替换表达式
                    rsstr = GetInitialExpressionSQL(rsstr, salarySolutionId);
                }
                return rsstr;
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
                return "0";
            }
        }
        /// <summary>
        /// 获取原始表达式的值SQL实现
        /// </summary>
        /// <param name="initFormula">原始表达式</param>
        /// <returns></returns>
        static double GetInitialFormulaDataValueSQL(string initFormulastring, string empId, string yearMonth, string salarySolutionId)
        {
            try
            {
                string rsstr = initFormulastring;
                string sql = string.Empty;
                DbSql dbsql = new DbSql();
                //替换表字段的表达式为值
                while (rsstr.Contains("["))
                {
                    //先找出[表.字段]
                    int startIndex = rsstr.IndexOf("[");
                    int endIndex = rsstr.IndexOf("]");
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    //将[表.字段]替换成数值
                    string temp = replacedStr.Substring(1, replacedStr.Length - 2);//取出表.字段
                    string[] token = temp.Split('.');//token[0]-表名,token[1]-列名
                    //在salSalaryRelationTable表中根据表名找到tableName
                    sql = "select ID,TableName,YearMonthField from salSalaryRelationTable where Name='" + token[0] + "'";
                    System.Data.DataTable relationTable = dbsql.ExecuteQuery(sql);
                    string tableName = relationTable.Rows[0][1].ToString();//tableName
                    string relationTableId = relationTable.Rows[0][0].ToString();
                    string yearMonthField = relationTable.Rows[0][2].ToString();
                    //获取字段名
                    sql = "select FieldName from salSalaryRelationFields where salRelationTableID='" + relationTableId + "' and FieldDes='" + token[1] + "'";
                    string fieldName = dbsql.GetSingle(sql).ToString();
                    sql = "select " + fieldName + " from " + tableName + " where EmployeeID='" + empId + "'";
                    //包含年月字段
                    if (yearMonthField != null && yearMonthField != string.Empty)
                    {
                        string tempYearMonth = yearMonth;
                        if (tableName == "xzEmpGJJ")
                        {
                            tempYearMonth = tempYearMonth.Replace("-", "");
                            tempYearMonth += " - " + tempYearMonth;
                        }
                        sql += " and " + yearMonthField + "='" + tempYearMonth + "'";
                    }
                    object tempObj = dbsql.GetSingle(sql);
                    string newStr = tempObj == null ? "0" : tempObj.ToString();
                    rsstr = rsstr.Replace(replacedStr, newStr);//替换成数值表达式
                }
                //替换函数为表达式
                while (rsstr.Contains("@"))
                {
                    //先找出<函数>
                    int startIndex = rsstr.IndexOf("@");
                    int endIndex = rsstr.IndexOf("#");
                    //函数名
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    string funName = replacedStr.Substring(1, replacedStr.Length - 2);
                    //获取函数表达式
                    sql = "select ID,rsReturn,Functions from salSalaryFunction where Name='" + funName + "'";
                    System.Data.DataTable funDt = dbsql.ExecuteQuery(sql);
                    string returnStr = "0";
                    if (funDt != null && funDt.Rows.Count > 0) //薪资函数存在,不存在该函数则为0
                    {
                        //函数返回表达式
                        returnStr = funDt.Rows[0][1].ToString();
                        if (returnStr == "" && returnStr != null)
                        {
                            //对有没有返回表达式的函数,考虑将其在后台实现函数功能
                            //通过反射获取函数,并执行函数
                            //先找出<参数>
                            string funId = funDt.Rows[0][0].ToString();
                            sql = "select DataValue from salSalaryFunctionParameter where SalaryFunctionID='" + funId + "'";
                            System.Data.DataTable parmDt = dbsql.ExecuteQuery(sql);
                            //目前只支持一个参数
                            string parmDataValue = parmDt.Rows[0][0].ToString();
                            //获取原始表达式
                            string InitExpression = GetInitialExpression(parmDataValue, salarySolutionId);
                            //获取参数值
                            double paramValue = GetInitialFormulaDataValue(InitExpression, empId, yearMonth, salarySolutionId);
                            //调用函数
                            string functionName = funDt.Rows[0][2].ToString();
                            if (functionName == string.Empty)
                            {
                                returnStr = "0";
                            }
                            else
                            {
                                Type type = typeof(ZX.BLL.fnSalary);
                                object[] parmArray = new object[] { paramValue };
                                MethodInfo mothodInfo = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
                                returnStr = mothodInfo == null ? "0" : mothodInfo.Invoke(null, parmArray).ToString();
                            }
                            rsstr = rsstr.Replace(replacedStr, returnStr);//替换成数值
                        }
                    }
                }
                Expression expression = new Expression(rsstr);
                double rs = expression.Compute(0);
                return rs;
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
                return 0;
            }
        }
        #endregion

        #region 以实体业务逻辑类解析
        /// <summary>
        /// 计算员工某个月份的工资
        /// </summary>
        /// <param name="emp">员工对象</param>
        /// <param name="yearMonth">年月</param>
        static void CalcEmployeeSalary(hrEmployee emp, string yearMonth)
        {
            try
            {
                salSalarySolution salarySolution = new salSalarySolution();
                BaseBussnies salarySoutionBll = new BaseBussnies(salarySolution);
                salDeptSolution deptSolution = new salDeptSolution();
                BaseBussnies deptSolutionBll = new BaseBussnies(deptSolution);
                salSalaryItem salaryItem = new salSalaryItem();
                BaseBussnies salaryItemBll = new BaseBussnies(salaryItem);
                IList<BaseEntity> listSalaryItems = null;
                BaseBussnies bll = new BaseBussnies();
                //根据员工ID获取薪资方案,计算其薪资
                //先判断是不否有个人薪资方案
                deptSolution = deptSolutionBll.GetEntityByCondition("DeptID='" + emp.ID.ToString() + "' and Flag=2") as salDeptSolution;
                if (deptSolution == null) //没有个人对应的薪资方案
                {
                    //查找相应的岗位薪资方案
                    //获取岗位
                    DatPost post = new DatPost();
                    BaseBussnies postBll = new BaseBussnies(post);
                    post = postBll.GetEntityById(emp.PostID.ToString()) as DatPost;
                    if (post != null)
                    {
                        deptSolution = deptSolutionBll.GetEntityByCondition("DeptID='" + post.PostID.ToString() + "' and Flag=1") as salDeptSolution;
                    }
                    if (deptSolution == null) //没有部门对应的薪资方案
                    {
                        //查找相应部门薪资方案
                        //根据员工ID获取所在部门
                        DatDepartment dept = new DatDepartment();
                        BaseBussnies deptbll = new BaseBussnies(dept);
                        dept = deptbll.GetEntityById(emp.DepartmentID.ToString()) as DatDepartment;
                        //部门薪资方案
                        if (dept != null)
                        {
                            deptSolution = deptSolutionBll.GetEntityByCondition("DeptID='" + dept.DeptID.ToString() + "' and Flag=0") as salDeptSolution;
                        }
                    }
                }
                if (deptSolution == null) return;//没有为该员工配置薪资方案
                //获取薪资方案所有薪资项
                listSalaryItems = salaryItemBll.GetEntitysByCondition("SalarySolutionID='" + deptSolution.SolutionID.ToString() + "'");
                //计算各薪资项的值
                //先删除该员工该年月薪资数据
                bll.RunSqlCommand("delete from salEmployeeSalaryResult where EmployeeID='" + emp.ID.ToString() + "' and YearMonth='" + yearMonth + "'");
                //构建薪资插入或更新SQL语句
                string rsSql = "insert into salEmployeeSalaryResult(ID,SalarySultionID,EmployeeID,YearMonth,BeginDate,EndDate,CalDate";
                List<double> resultLists = new List<double>();
                if (listSalaryItems == null) return;
                foreach (BaseEntity entity in listSalaryItems)
                {
                    salSalaryItem tempSalaryItem = entity as salSalaryItem;
                    double rs = GetInitialFormulaDataValue(tempSalaryItem.Formula, emp.ID.ToString(), yearMonth, deptSolution.SolutionID.ToString());//计算结果
                    rsSql += "," + tempSalaryItem.ItemName;
                    resultLists.Add(rs);//保存到结果列表中
                }
                DateTime date = DateTime.Parse(yearMonth);
                string startDate = date.ToString("yyyy-MM-dd");
                date = date.AddMonths(1);
                date = date.AddDays(-1);
                string endDate = date.ToString("yyyy-MM-dd");
                rsSql += ") values(newid(),'" + deptSolution.SolutionID.ToString() + "','" + emp.ID.ToString() + "','" + yearMonth + "','" + startDate + "','" + endDate + "','" + DateTime.Now.ToString("yyyy-MM-dd") + "'";
                foreach (double d in resultLists)
                {
                    rsSql += "," + d;
                }
                rsSql += ")";
                //将数据插入结果表
                bll.RunSqlCommand(rsSql);
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
            }
        }

        /// <summary>
        /// 将蒋项表达式转换成原始表达式
        /// </summary>
        /// <param name="formula"></param>
        /// <param name="salarySolutionId"></param>
        /// <returns></returns>
        public static string GetInitialExpression(string formula, string salarySolutionId)
        {
            try
            {
                string rsstr = formula;
                //替换函数为表达式
                while (rsstr.Contains("<"))
                {
                    //先找出<函数>
                    int startIndex = rsstr.IndexOf("<");
                    int endIndex = rsstr.IndexOf(">");
                    //函数名
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    string funName = replacedStr.Substring(1, replacedStr.Length - 2);
                    //获取函数表达式
                    salSalaryFunction salaryFun = new salSalaryFunction();
                    BaseBussnies salaryFunBll = new BaseBussnies(salaryFun);
                    salaryFun = salaryFunBll.GetEntityByCondition("Name='" + funName + "'") as salSalaryFunction;
                    string returnStr = "0";
                    if (salaryFun != null) //薪资函数存在,不存在该函数则为0
                    {
                        //函数返回表达式
                        salSalaryFunctionParameter salaryParam = new salSalaryFunctionParameter();
                        BaseBussnies salaryParamBll = new BaseBussnies(salaryParam);
                        returnStr = salaryFun.rsReturn;
                        //函数有返回值表明该函数是表达式函数,否则在GetInitialFormulaDataValue获取其值
                        if (returnStr.Trim() != string.Empty)
                        {
                            //把函数中的参数替换为值
                            while (returnStr.Contains("<"))
                            {
                                //先找出<参数>
                                int index1 = returnStr.IndexOf("<");
                                int index2 = returnStr.IndexOf(">");
                                string replacedParamStr = returnStr.Substring(index1, index2 - index1 + 1);
                                //参数名
                                string paramName = replacedParamStr.Substring(1, replacedParamStr.Length - 2);
                                //获取参数值
                                salaryParam = salaryParamBll.GetEntityByCondition("Parameter='" + paramName + "' and SalaryFunctionID='" + salaryFun.ID.ToString() + "'") as salSalaryFunctionParameter;
                                returnStr = returnStr.Replace(replacedParamStr, salaryParam.DataValue);
                            }
                            rsstr = rsstr.Replace(replacedStr, "(" + returnStr + ")");
                        }
                        else //表明该函数为后台反射调用执行的函数
                        {
                            //这类函数用@函数名#标示
                            rsstr = rsstr.Replace(replacedStr, "@" + funName + "#");
                        }
                        //递归替换表达式
                        rsstr = GetInitialExpression(rsstr, salarySolutionId);
                    }
                }
                //替换薪资项为表达式
                while (rsstr.Contains("{"))
                {
                    //先找出{薪资项}
                    int startIndex = rsstr.IndexOf("{");
                    int endIndex = rsstr.IndexOf("}");
                    //要替换的
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    //薪资项目说明
                    string salaryItemNote = replacedStr.Substring(1, replacedStr.Length - 2);
                    //获取薪资项表达式
                    salSalaryItem salaryItem = new salSalaryItem();
                    BaseBussnies salaryItemBll = new BaseBussnies(salaryItem);
                    salaryItem = salaryItemBll.GetEntityByCondition("ItemNotes='" + salaryItemNote + "' and SalarySolutionID='" + salarySolutionId + "'") as salSalaryItem;
                    if (salaryItem == null) //该薪资方案中不存在该薪资项
                    {
                        rsstr = rsstr.Replace(replacedStr, "0");
                    }
                    else
                    {
                        rsstr = rsstr.Replace(replacedStr, "(" + salaryItem.DataSource + ")");
                    }
                    //递归替换表达式
                    rsstr = GetInitialExpression(rsstr, salarySolutionId);
                }
                return rsstr;
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
                return "0";
            }
        }

        /// <summary>
        /// 获取原始表达式的值
        /// </summary>
        /// <param name="initFormula">原始表达式</param>
        /// <returns></returns>
        static double GetInitialFormulaDataValue(string initFormulastring, string empId, string yearMonth, string salarySolutionId)
        {
            try
            {
                string rsstr = initFormulastring;
                //替换表字段的表达式为值
                while (rsstr.Contains("["))
                {
                    //先找出[表.字段]
                    int startIndex = rsstr.IndexOf("[");
                    int endIndex = rsstr.IndexOf("]");
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    //将[表.字段]替换成数值
                    string temp = replacedStr.Substring(1, replacedStr.Length - 2);//取出表.字段
                    string[] token = temp.Split('.');//token[0]-表名,token[1]-列名
                    //在salSalaryRelationTable表中根据表名找到tableName
                    salSalaryRelationTable salaryRelationTable = new salSalaryRelationTable();
                    BaseBussnies tempbll = new BaseBussnies(salaryRelationTable);
                    salaryRelationTable = tempbll.GetEntityByCondition("Name='" + token[0] + "'") as salSalaryRelationTable;
                    string tableName = salaryRelationTable.TableName;//tableName
                    //获取字段名
                    salSalaryRelationFields salaryRationField = new salSalaryRelationFields();
                    BaseBussnies salaryFieldBll = new BaseBussnies(salaryRationField);
                    salaryRationField = salaryFieldBll.GetEntityByCondition("salRelationTableID='" + salaryRelationTable.ID + "' and FieldDes='" + token[1] + "'") as salSalaryRelationFields;
                    string sql = "select " + salaryRationField.FieldName + " from " + tableName + " where EmployeeID='" + empId + "'";
                    //包含年月字段
                    if (salaryRelationTable.YearMonthField.Trim() != string.Empty)
                    {
                        string tempYearMonth = yearMonth;
                        if (tableName == "xzEmpGJJ")
                        {
                            tempYearMonth = tempYearMonth.Replace("-", "");
                            tempYearMonth += " - " + tempYearMonth;
                        }
                        sql += " and " + salaryRelationTable.YearMonthField.Trim() + "='" + tempYearMonth + "'";
                    }
                    BaseBussnies bll = new BaseBussnies();
                    System.Data.DataTable dt = bll.GetDataBySqlComm(sql);
                    string newStr = dt.Rows.Count == 0 ? "0" : dt.Rows[0][0].ToString();
                    rsstr = rsstr.Replace(replacedStr, newStr);//替换成数值表达式
                }
                //替换函数为表达式
                while (rsstr.Contains("@"))
                {
                    //先找出<函数>
                    int startIndex = rsstr.IndexOf("@");
                    int endIndex = rsstr.IndexOf("#");
                    //函数名
                    string replacedStr = rsstr.Substring(startIndex, endIndex - startIndex + 1);
                    string funName = replacedStr.Substring(1, replacedStr.Length - 2);
                    //获取函数表达式
                    salSalaryFunction salaryFun = new salSalaryFunction();
                    BaseBussnies salaryFunBll = new BaseBussnies(salaryFun);
                    salaryFun = salaryFunBll.GetEntityByCondition("Name='" + funName + "'") as salSalaryFunction;
                    string returnStr = "0";
                    if (salaryFun != null) //薪资函数存在,不存在该函数则为0
                    {
                        //函数返回表达式
                        salSalaryFunctionParameter salaryParam = new salSalaryFunctionParameter();
                        BaseBussnies salaryParamBll = new BaseBussnies(salaryParam);
                        returnStr = salaryFun.rsReturn;
                        if (returnStr == "")
                        {
                            //对有没有返回表达式的函数,考虑将其在后台实现函数功能
                            //通过反射获取函数,并执行函数
                            //先找出<参数>
                            IList<BaseEntity> listFunParams = salaryParamBll.GetEntitysByCondition("SalaryFunctionID='" + salaryFun.ID.ToString() + "'");
                            //目前只支持一个参数
                            salaryParam = listFunParams[0] as salSalaryFunctionParameter;
                            //获取原始表达式
                            string InitExpression = GetInitialExpression(salaryParam.DataValue, salarySolutionId);
                            //获取参数值
                            double paramValue = GetInitialFormulaDataValue(InitExpression, empId, yearMonth, salarySolutionId);
                            //调用函数
                            if (salaryFun.Functions.Trim() == string.Empty)
                            {
                                returnStr = "0";
                            }
                            else
                            {
                                Type type = typeof(ZX.BLL.fnSalary);
                                object[] parmArray = new object[] { paramValue };
                                MethodInfo mothodInfo = type.GetMethod(salaryFun.Functions, BindingFlags.Public | BindingFlags.Static);
                                returnStr = mothodInfo == null ? "0" : mothodInfo.Invoke(null, parmArray).ToString();
                            }
                            rsstr = rsstr.Replace(replacedStr, returnStr);//替换成数值
                        }
                    }
                }
                Expression expression = new Expression(rsstr);
                double rs = expression.Compute(0);
                return rs;
            }
            catch (Exception ex)
            {
                try
                {
                    salSalarylErrorLog salaryErrLog = new salSalarylErrorLog();
                    BaseBussnies errBll = new BaseBussnies(salaryErrLog);
                    salaryErrLog.moduleName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                    salaryErrLog.className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
                    salaryErrLog.methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                    salaryErrLog.errMsg = ex.Message;
                    salaryErrLog.errDate = DateTime.Now;
                    errBll.Insert();
                }
                catch { }
                return 0;
            }
        }
        #endregion
    }

    /// <summary>    
    /// 处理表达试运算---动态生成数学表达式并计算其值    
    /// 表达式使用 C# 语法，可带一个的自变量(x)。    
    /// 表达式的自变量和值均为(double)类型。    
    /// </summary>    
    /// <example>    
    /// <code>    
    /// Expression expression = new Expression("Math.Sin(x)");     
    /// Console.WriteLine(expression.Compute(Math.PI / 2));     
    /// expression = new Expression("double u = Math.PI - x;" +     
    /// "double pi2 = Math.PI * Math.PI;" +     
    /// "return 3 * x * x + Math.Log(u * u) / pi2 / pi2 + 1;");     
    /// Console.WriteLine(expression.Compute(0));     
    ///     
    /// Expression expression = new Expression("return 10*(5+5)/10;");    
    /// Response.Write(expression.Compute(0));    
    /// Response.End();    
    /// </code>    
    /// </example>    
    class Expression
    {
        object instance;
        MethodInfo method;
        /// <summary>        
        /// 表达试运算        
        /// </summary>        
        /// <param name="expression">表达试</param>        
        public Expression(string expression)
        {
            if (expression.IndexOf("return") < 0)
                expression = "return " + expression + ";";
            string className = "Expression";
            string methodName = "Compute";
            CompilerParameters p = new CompilerParameters();
            p.GenerateInMemory = true;
            CompilerResults cr = new CSharpCodeProvider().CompileAssemblyFromSource(p, string.Format("using System;sealed class {0}{{public double {1}(double x){{{2}}}}}", className, methodName, expression));
            if (cr.Errors.Count > 0)
            {
                string msg = "Expression(\"" + expression + "\"): /n";
                foreach (CompilerError err in cr.Errors)
                    msg += err.ToString() + "/n";
                throw new Exception(msg);
            }
            instance = cr.CompiledAssembly.CreateInstance(className);
            method = instance.GetType().GetMethod(methodName);
        }
        /// <summary>        
        /// 处理数据        
        /// </summary>        
        /// <param name="x"></param>        
        /// <returns>返回计算值</returns>        
        public double Compute(double x)
        {
            return (double)method.Invoke(instance, new object[] { x });
        }
    }
}
